
import { _decorator, Component, Node, math } from 'cc';
import { Role } from './Role';
import { GlobalEnum } from '../../Script/GameSpecial/GlobalEnum';
import GlobalData from '../../Script/Common/GlobalData';
import GameConfig from '../../Script/GameSpecial/GameConfig';
import MapData from '../../Script/GameSpecial/MapData';
import { EventType } from '../../Script/GameSpecial/GameEventType';
import PlayerData from '../../Script/Common/PlayerData';
const { ccclass, property } = _decorator;

@ccclass('Enemy')
export class Enemy extends Role {

    protected registAllCustomUpdate() {
        this.registCustomUpdate(GlobalEnum.RoleState.stand, this.stepStand);
        this.registCustomUpdate(GlobalEnum.RoleState.move, this.stepForward);
        this.registCustomUpdate(GlobalEnum.RoleState.forward, this.stepForward);
        this.registCustomUpdate(GlobalEnum.RoleState.endRoad, this.stepEndRoad);
        this.registCustomUpdate(GlobalEnum.RoleState.rotateToColler, this.stepRotateToColler);

        this.registCustomUpdate(GlobalEnum.RoleState.moveOnBadTerrain, this.stepMoveOnBadTerrain);
        this.registCustomUpdate(GlobalEnum.RoleState.moveToScoreLine, this.stepMoveToScoreLine);
        this.registCustomUpdate(GlobalEnum.RoleState.moveOnScoreRoad, this.stepMoveOnScoreRoad);

    }
    public enterLevel(data?: { z?: number, radian: number }) {
        if (!!data) {
            if (undefined !== data.z) {
                this.node.setPosition(0, 0, data.z);
                this.node.getPosition(this.cachePos);
            }
            if (undefined !== data.radian) {
                this.setRadianZ(data.radian);
                this.setTargetRadianZ(data.radian);
            }
        }
        this.enterCustomUpdateState(GlobalEnum.RoleState.stand);
        this.setCar(1, 0);
        this.once(EventType.LevelEvent.startJoy, this.startLevel, this);
        this.forwardElapsed = 1 - Math.random() * 3;
        // let v = Math.random();
        // if (v < 0.6) {
        //     this.checkBarrier();
        // } else if (v < 0.8) {
        //     this.checkPart();
        // } else {
        //     this.enterCustomUpdateState(GlobalEnum.RoleState.forward);
        // }
    }

    protected enterTerrain(terrain) {
        this.node.active = true;
        this.terrain = terrain;
        this.speedScale = 0.5;
        this.updateSpeed();
        this.hideHuoYan();
    }

    protected forwardElapsed: number = 0;
    protected stepForward(dt: number) {
        this.stepMoving(dt);
        this.checkActive();
        this.forwardElapsed += dt;
        if (this.forwardElapsed > 2) {
            this.forwardElapsed = 0;
            this.changeRunMode();
        }
        this.checkArrived();
    }

    protected checkArrived() {
        if (this.node.position.z + MapData.getTotalLen() < 0) {
            this.node.active = true;
            this.setTargetRadianZ(this.radianZ);
            this.enterCustomUpdateState(GlobalEnum.RoleState.endRoad);
            this.emit(EventType.LevelEvent.enemyArrived, this);
            return true;
        }
        return false;
    }

    protected stepRotateToColler(dt: number) {
        this.stepMoving(dt);
        this.checkActive();
        this.checkLevelColler();
        this.checkArrived();
    }
    protected checkLevelColler() {
        if (!this.targetColler || this.maxZ < this.targetColler.minZ) {
            this.targetColler = null;
            this.carLayer.setRotation(0, 0, 0, 1);
            this.changeRunMode();
        }
    }
    //随机变更AI行为模式
    protected changeRunMode() {
        let z = GlobalData.get(GlobalEnum.myGlobalDataType.player).z;
        let v = Math.random();
        if (this.z - 20 > z && v < 0.3) {
            this.changeRunForFast();
            return;
        }
        v = Math.random();
        if (v < 0.2) {
            this.checkBarrier();
        } else if (v < 0.4) {
            this.checkPart();
        } else {
            this.enterCustomUpdateState(GlobalEnum.RoleState.forward);
        }
    }
    protected changeRunForFast() {
        //作弊：强行添加零件
        let count = PlayerData.getData("gameData.curLevel");
        if (count > 30) count = 30;
        this.car.setPartCount(this.curPartCount + count);
        this.curPartCount = this.car.getPartCount();
        this.updateSpeed();

        let data = GlobalData.get(GlobalEnum.myGlobalDataType.levelCollItems);
        let collers1 = data[GlobalEnum.CollerType.barrierGroup];
        let c1 = collers1[this.collPtr[GlobalEnum.CollerType.barrierGroup].min];
        if (!c1) {
            this.checkPart();
            return;
        }
        let collers2 = data[GlobalEnum.CollerType.carPart];
        let c2 = collers2[this.collPtr[GlobalEnum.CollerType.carPart].min];
        if (!c2) {
            this.checkBarrier();
            return;
        }
        if (c1.z > c2.z) {
            this.checkBarrier();
        } else {
            this.checkPart();
        }
    }

    protected enterRotate(coller, radian) {
        this.targetColler = coller;
        this.setTargetRadianZ(radian);
        this.enterCustomUpdateState(GlobalEnum.RoleState.rotateToColler);
    }

    protected targetColler = null;

    //检测并躲避前方障碍物
    protected checkBarrier() {
        let ptr = this.collPtr[GlobalEnum.CollerType.barrierGroup].min;
        let data = GlobalData.get(GlobalEnum.myGlobalDataType.levelCollItems);
        let collers = data[GlobalEnum.CollerType.barrierGroup];
        let coller = collers[ptr];
        if (!coller) {
            this.enterCustomUpdateState(GlobalEnum.RoleState.forward);
            return;
        }
        let minRadian = coller.minRadian;
        let maxRadian = coller.maxRadian;
        if (this.minRadian > maxRadian || this.maxRadian < minRadian) {
            return;
        }
        let targetRadian = 0;
        if (coller.node.name == "LeftBarrierGroup") {
            targetRadian = Math.random() * GameConfig.GameRule.roadMaxRadian;
        } else if (coller.node.name == "RightBarrierGroup") {
            targetRadian = Math.random() * GameConfig.GameRule.roadMinRadian;
        } else {
            if (Math.random() < 0.5) {
                let rs = GameConfig.GameRule.roadMinRadian - minRadian;
                targetRadian = minRadian + Math.random() * rs;
            } else {
                let rs = GameConfig.GameRule.roadMaxRadian - maxRadian;
                targetRadian = maxRadian + Math.random() * rs;
            }
        }
        this.enterRotate(coller, targetRadian);
    }


    //拾取零件
    protected checkPart() {
        let ptr = this.collPtr[GlobalEnum.CollerType.carPart].min;
        let data = GlobalData.get(GlobalEnum.myGlobalDataType.levelCollItems);
        let collers = data[GlobalEnum.CollerType.carPart];
        let coller = collers[ptr];
        if (!coller) {
            this.enterCustomUpdateState(GlobalEnum.RoleState.forward);
            return;
        }
        let targetRadian = (coller.minRadian + coller.maxRadian) * 0.5;
        let minRadian = coller.minRadian;
        let maxRadian = coller.maxRadian;
        if (this.minRadian < maxRadian && this.maxRadian > minRadian) {
            targetRadian = this.radianZ;
        }
        this.enterRotate(coller, targetRadian);
    }

    //在玩家视野之外时隐藏自身
    private checkActive() {
        let z = GlobalData.get(GlobalEnum.myGlobalDataType.player).z;
        let z0 = this.node.position.z;
        if (this.node.active) {
            if (z - z0 > 120 || z0 - z > 20) {
                this.node.active = false;
            }
        } else {
            if (z - z0 < 100 && z0 - z < 10) {
                this.node.active = true;
            }
        }
    }
}

